#pragma once

#include <cassert>
#include "ShmMessageNodeQueue.hpp"
#include "ShmScopedLock.hpp"
#include "ShmCond.hpp"
#include "ShmMutex.hpp"
#include "ShmMessagePool.hpp"

class ShmMessageNodeLockQueue
{
public:
    // 构造函数，接受队列容量和共享消息池
    ShmMessageNodeLockQueue(uint32_t capacity)
        : _queue(capacity)
        , _MaxCapacity(capacity)
        , isClose(false) {
        assert(_MaxCapacity > 0);
    }

    ~ShmMessageNodeLockQueue() {}

    // 关闭队列
    void close(ShmMessagePool& pool) {
        {
            ShmScopedLock lock(_mtx);  // 加锁
            _queue.Clear(pool);            // 清空队列
            isClose = true;            // 设置关闭标志
        }

        // 唤醒所有阻塞的生产者和消费者
        _Producer.Broadcast();
        _Consumer.Broadcast();
    }

    // 尝试唤醒一个消费者
    void flush() {
        _Consumer.Signal();  // 唤醒一个等待的消费者
    }

    // 清空队列
    void clear(ShmMessagePool& pool) {
        ShmScopedLock lock(_mtx);  // 加锁

        _queue.Clear(pool);            // 清空队列
    }

    // 检查指定节点是否是队头
    bool isHead(ShmMessageNode* node) {
        ShmScopedLock lock(_mtx);  // 加锁

        return _queue.isHead(node);
    }

    // 查看队首元素
    ShmMessageNode* front(ShmMessagePool& pool) {
        ShmScopedLock lock(_mtx);  // 加锁

        while (_queue.Empty()) {
            // 队列为空消费者阻塞
            _Consumer.Wait(_mtx);
            if (isClose)
                return nullptr;  // 如果队列关闭，返回 nullptr
        }
        return _queue.Front(pool);  // 返回队首元素
    }

    // 获取队列当前元素个数
    uint32_t size() {
        ShmScopedLock lock(_mtx);  // 加锁
        return _queue.Size();      // 返回队列大小
    }

    // 获取队列最大容量
    uint32_t capacity() {
        ShmScopedLock lock(_mtx);  // 加锁
        return _MaxCapacity;       // 返回队列最大容量
    }

    // 尾插一个元素
    void push(ShmMessageNode* node, ShmMessagePool& pool) {
        ShmScopedLock lock(_mtx);  // 加锁

        while (_queue.Size() >= _MaxCapacity) {
            _Producer.Wait(_mtx);
            if (isClose)
                return;  // 如果队列关闭，返回
        }
        _queue.Push_Back(node, pool);  // 将节点加入队尾
        _Consumer.Signal();      // 唤醒一个消费者
    }

    // 队列是否为空
    bool empty() {
        ShmScopedLock lock(_mtx);  // 加锁
        return _queue.Empty();     // 返回队列是否为空
    }

    // 队列是否满了
    bool full() {
        ShmScopedLock lock(_mtx);  // 加锁
        return _queue.Full();      // 返回队列是否已满
    }

    // 移除队首一个元素，自动释放
    void pop(ShmMessagePool& pool) {
        ShmScopedLock lock(_mtx);  // 加锁
        while (_queue.Empty()) {
            // 队列为空消费者阻塞
            _Consumer.Wait(_mtx);
            if (isClose)
                return;  // 如果队列关闭，返回
        }
        _queue.Pop(pool);        // 移除队首元素
        _Producer.Signal();  // 唤醒一个生产者
    }

private:
    uint32_t _MaxCapacity;             // 最大容量
    bool isClose;                      // 队列是否关闭
    ShmMutex _mtx;                     // 锁
    ShmCond _Consumer;                 // 消费者条件变量
    ShmCond _Producer;                 // 生产者条件变量
    ShmMessageNodeQueue _queue;        // 普通队列
};
